<template>
  <view
    class="container"
    :style="pageLoadding || showResult ? 'overflow-y:hidden;height:100%' : ''"
  >
    <view class="tui-searchbox search-box">
      <view class="tui-bottom-item" :class="[popup ? 'tui-btmItem-active' : '']" @tap="showPopup">
        <view
          class="tui-bottom-text"
          :class="[popup ? 'tui-active' : '']"
        >{{ sources[selected].name }}</view>
        <tui-icon
          :name="popup ? 'arrowup' : 'arrowdown'"
          :size="14"
          :color="popup ? '#6cc' : '#444'"
        ></tui-icon>
      </view>
      <view class="tui-search-input">
        <icon type="search" :size="13" color="#333"></icon>
        <input
          ref="searchInput"
          class="tui-input"
          placeholder-class="tui-input-plholder"
          confirm-type="search"
          placeholder="书名、作者、关键字"
          auto-focus
          :focus="focus"
          v-model.trim="key"
          @confirm="search"
        />
        <icon type="clear" :size="13" color="#bcbcbc" @tap="clear" v-show="key"></icon>
      </view>
      <view class="tui-cancle" hover-class="tui-btn-gray" @tap="search">搜索</view>
    </view>
    <tui-top-dropdown :show="popup" :paddingbtm="110" :translatey="128" @close="btnCloseDrop">
      <scroll-view class="tui-scroll-box" scroll-y scroll-with-animation>
        <view class="tui-seizeaseat-20"></view>
        <view
          class="tui-drop-item"
          :class="[item.selected ? 'tui-bold' : '']"
          v-for="(item, index) in sources"
          :key="index"
          @tap.stop="btnSelected"
          :data-index="index"
        >
          <text
            class="tui-ml tui-middle"
            :class="{ 'tui-active': index == selected }"
          >{{ item.name }} ({{ item.url }})</text>
        </view>
        <view class="tui-seizeaseat-30"></view>
      </scroll-view>
    </tui-top-dropdown>

    <template v-if="showResult">
      <swiper class="swiper-content" :current="selected" :duration="300" @change="selecteSource">
        <swiper-item class="swiper-item-content" v-for="(dataList, idk) in resultData" :key="idk">
          <scroll-view scroll-y enableBackToTop="true" @scrolltolower="loadMore">
            <tui-list-view>
              <tui-list-cell
                :class-name="
                  'animated fadeInRight delay-z' +
                    (index - (dataList.pageIndex - 1) * 6) * 2
                "
                v-for="(item, index) in dataList.list"
                :key="index"
                :index="index"
                @click="detail"
              >
                <view class="tui-flex tui-flex-1">
                  <image v-if="item.cover" mode="widthFix" :src="item.cover" style="width:150rpx;" />
                  <view class="tui-flex-1 tui-flex tui-flex-column" style="padding-left:20rpx;">
                    <view class="tui-flex">
                      <view
                        class="tui-flex-1"
                        style="font-weight:bold;font-size:38rpx;"
                      >{{ item.name }}</view>
                      <tui-button
                        v-if="item.inBookshelf != 0"
                        size="small"
                        :disabled="item.inBookshelf == 1"
                        :type="
                          item.inBookshelf == 1
                            ? 'gray'
                            : item.inBookshelf
                            ? 'warning'
                            : 'danger'
                        "
                        :loading="item.loading"
                        :stop="true"
                        @click="addBookshelf(index)"
                      >
                        {{
                        item.inBookshelf == 1
                        ? "已添加"
                        : item.inBookshelf
                        ? "加备用源"
                        : "加书架"
                        }}
                      </tui-button>
                    </view>
                    <view class="tui-flex" style="font-size:28rpx;">
                      <view class="tui-flex-1">
                        <tui-icon name="people" :size="28" :rpx="true" color="#6cc" />
                        {{ " " + item.author }}
                      </view>
                      <view style="color:#ccc;font-size:26rpx;">
                        <text v-if="item.status">{{ item.status }} |</text>
                        {{ item.category || "" }}
                      </view>
                    </view>
                    <view
                      v-if="item.latest_chapter_name"
                      class="tui-flex"
                      style="color:#555;font-size:26rpx;"
                    >最新章节：{{ item.latest_chapter_name }}</view>
                    <view
                      v-if="item.update_time"
                      class="tui-flex"
                      style="color:#555;font-size:26rpx;"
                    >更新时间：{{ item.update_time }}</view>
                    <view class="story-description">{{ item.description }}</view>
                  </view>
                </view>
              </tui-list-cell>
            </tui-list-view>
            <tui-loadmore :visible="dataList.loadding"></tui-loadmore>
            <tui-nomore :visible="!dataList.hasMore"></tui-nomore>
          </scroll-view>
        </swiper-item>
      </swiper>
    </template>
    <view class="search-box-top" v-else>
      <view class="tui-search-history" v-if="history.length > 0">
        <view class="tui-history-header">
          <view class="tui-search-title">搜索历史</view>
          <tui-icon
            name="delete"
            :size="14"
            color="#333"
            @tap="openActionSheet"
            class="tui-icon-delete"
          ></tui-icon>
        </view>
        <view class="tui-history-content">
          <block v-for="(item, index) in history" :key="index">
            <tui-tag type="light-gray" shape="circle" @click="tapSearch(item)">{{ item }}</tui-tag>
          </block>
        </view>
      </view>

      <view class="tui-search-hot">
        <view class="tui-hot-header">
          <view class="tui-search-title">大家正在搜</view>
        </view>
        <view class="tui-hot-content">
          <block v-for="(item, index) in hot" :key="index">
            <tui-tag type="light-gray" shape="circle" @click="tapSearch(item)">{{ item }}</tui-tag>
          </block>
        </view>
      </view>
      <tui-actionsheet
        :show="showActionSheet"
        tips="确认清空搜索历史吗？"
        @click="itemClick"
        @cancel="closeActionSheet"
      ></tui-actionsheet>
    </view>
    <tui-page-loading class-name="loader3" :show="pageLoadding" />
  </view>
</template>

<script>
import tuiIcon from "@/components/icon/icon";
import tuiTag from "@/components/tag/tag";
import tuiActionsheet from "@/components/actionsheet/actionsheet";
import tuiSearchBoxBtn from "@/components/search-box-btn/search-box-btn.vue";
import tuiListView from "@/components/list-view/list-view.vue";
import tuiListCell from "@/components/list-cell/list-cell.vue";
import tuiButton from "@/components/button/button.vue";
import tuiLoadmore from "@/components/loadmore/loadmore";
import tuiNomore from "@/components/nomore/nomore";
import tuiTopDropdown from "@/components/top-dropdown/top-dropdown";
import tuiPageLoading from "@/components/page-loading/page-loading.vue";
import { mapState, mapMutations } from "vuex";
import { equalUrl } from "@/utils/util";

export default {
  components: {
    tuiIcon,
    tuiTag,
    tuiActionsheet,
    tuiSearchBoxBtn,
    tuiListView,
    tuiListCell,
    tuiButton,
    tuiLoadmore,
    tuiNomore,
    tuiPageLoading,
    tuiTopDropdown
  },
  data() {
    return {
      key: "",
      history: [],
      hot: [],
      showActionSheet: false,
      showResult: false,
      pageLoadding: false,
      resultData: [],
      // 聚焦顶部搜索框
      focus: true,
      // 打开切换源的面板
      popup: false,
      // 源列表
      sources: [],
      selected: 0,
      winHeight: uni.getSystemInfoSync().windowHeight - uni.upx2px(128)
    };
  },
  computed: {
    ...mapState(["bookshelfs"])
  },
  watch: {
    bookshelfs(val, oldVal) {
      this.resultData.forEach(arr => {
        arr.list.forEach(item => {
          if (!item.inBookshelf || item.inBookshelf == -1) {
            item.inBookshelf = this.isInBookshelf(item);
          }
        });
      });
    },
    key() {
      if (!this.key) {
        this.showResult = false;
      }
    }
  },
  onLoad() {
    this.init();
  },
  methods: {
    ...mapMutations(["setBookshelfs"]),
    init() {
      // 搜索历史
      this.db
        .collection("search_histories")
        .limit(10)
        .orderBy("updated_at", "desc")
        .get()
        .then(res => {
          this.history = res.data.map(item => item.name);
        })
        .catch(console.error);
      // 搜索最多
      this.db
        .collection("search_count")
        .where({ count: this.db.command.gt(100) })
        .orderBy("count", "desc")
        .limit(10)
        .get()
        .then(res => {
          this.hot = res.data.map(item => item.name);
        })
        .catch(console.error());
      this.db
        .collection("book_sources")
        .where({
          enable: true
        })
        .orderBy("order", "asc")
        .field({
          _id: true,
          name: true,
          url: true,
          pageSize: true
        })
        .get()
        .then(res => {
          if (res.data && res.data.length > 0) {
            this.sources = res.data;
            this.initReuslt();
          }
        })
        .catch(err => {
          console.error(err);
        });
    },
    initReuslt() {
      this.resultData = [];
      this.sources.forEach(s => {
        this.resultData.push({
          list: [],
          loadData: [],
          pageIndex: 1,
          loadding: false,
          hasMore: true
        });
      });
    },
    clear() {
      this.key = "";
      // 重新聚焦
      this.focus = false;
      this.$nextTick(function() {
        this.focus = true;
      });
      this.showResult = false;
    },
    closeActionSheet: function() {
      this.showActionSheet = false;
    },
    openActionSheet: function() {
      this.showActionSheet = true;
    },
    itemClick: function(e) {
      let index = e.index;
      if (index == 0) {
        this.showActionSheet = false;
        // 清空搜索历史
        this.callFunc({
          name: "deleteSearchHistory"
        }).then(res => {
          if (res.errMsg == "cloud.callFunction:ok") {
            this.tui.toast("删除成功");
            this.history = [];
          } else {
            this.tui.toast("删除失败");
          }
        });
      }
    },
    tapSearch(value) {
      this.key = value;
      this.search();
    },
    loadMore() {
      const { loadData, hasMore } = this.resultData[this.selected];
      if (loadData.length > 0) {
        // 已预加载完毕，直接追加列表，并预加载下一页
        this.resultData[this.selected].pageIndex++;
        this.resultData[this.selected].list.push(...loadData);
        if (loadData.length < this.sources[this.selected].pageSize) {
          this.resultData[this.selected].hasMore = false;
          this.resultData[this.selected].loadData = [];
        } else {
          this.preLoad(this.selected);
        }
      } else if (hasMore) {
        // 标记已触过底，等待预加载完毕后，立即追加
        this.resultData[this.selected].loadding = true;
      }
    },
    // 预加载
    preLoad(selected = this.selected) {
      this.resultData[selected].loadData = [];
      this.searchItem(
        this.resultData[selected].pageIndex + 1,
        this.sources[selected]._id
      ).then(data => {
        if (this.resultData[selected].loadding) {
          this.resultData[selected].pageIndex++;
          this.resultData[selected].list.push(...data);
          this.resultData[selected].loadding = false;
          if (data.length < this.sources[selected].pageSize) {
            this.resultData[selected].hasMore = false;
          } else {
            this.preLoad(selected);
          }
        } else {
          // 还没有触底，先把预加载的数据储存，不追加列表
          this.resultData[selected].loadData = data;
        }
      });
    },
    search(reinit = true) {
      if (!this.sources[this.selected]._id) {
        this.tui.toast("没有选择源");
        return;
      }
      const value = this.key;
      if (!value) {
        this.tui.toast("请输入搜索内容");
      } else {
        if (reinit) this.initReuslt();
        this.pageLoadding = true;
        const index = this.history.indexOf(value);
        if (index > -1) {
          this.history.splice(index, 1);
        }
        this.history.unshift(value);

        this.searchItem()
          .then(data => {
            // console.log(data, this.resultData, this.selected);
            this.resultData[this.selected].list = data;
            if (data.length < this.sources[this.selected].pageSize) {
              this.resultData[this.selected].hasMore = false;
            } else {
              this.resultData[this.selected].hasMore = true;
              this.preLoad(this.selected);
            }
            this.showResult = true;
            this.pageLoadding = false;
          })
          .catch(err => {
            const error = JSON.stringify(err);
            if (error.indexOf("exection timeout")) {
              this.tui.toast("请求超时了");
            } else {
              this.tui.toast("发生错误了");
            }
            console.log(JSON.stringify(err));
            this.pageLoadding = false;
          });
      }
    },
    // 由于小程序云开发最长20s请求超时，所以一页中的数据分多次请求
    async searchItem(
      pageIndex = this.resultData[this.selected].pageIndex,
      source_id = this.sources[this.selected]._id
    ) {
      const data = [];
      const res = await this.callFunc({
        name: "search",
        data: {
          source_id,
          value: this.key,
          pageIndex
        }
      });
      if (res.result && res.result.errMsg == "ok") {
        res.result.data.forEach(item => {
          item.inBookshelf = this.isInBookshelf(item);
          data.push(item);
        });
      } else {
        this.tui.toast(res.result.errMsg);
      }
      // console.log(data);
      return data;
    },
    // 是否在书架中
    isInBookshelf(item) {
      const book = this.bookshelfs.find(
        bs => bs.name == item.name && bs.author == item.author
      );
      if (!book) {
        return 0;
      }
      if (
        book.source_id == item.source_id &&
        equalUrl(book.read_url, item.read_url)
      ) {
        return 1;
      } else if (
        book.other_sources &&
        book.other_sources.some(
          os =>
            os.source_id == item.source_id &&
            equalUrl(os.read_url, item.read_url)
        )
      ) {
        return 1;
      }
      return -1;
    },
    // 加入书架
    addBookshelf(index) {
      this.$set(this.resultData[this.selected].list[index], "loading", true);
      const {
        name,
        author,
        read_url,
        cover,
        source_id,
        first_chapter_url,
        latest_chapter_url
      } = this.resultData[this.selected].list[index];
      this.callFunc({
        name: "addBookshelf",
        data: {
          name,
          author,
          cover,
          source_id,
          read_url,
          latest_chapter_url,
          url: first_chapter_url
        }
      }).then(res => {
        if (res.result.errMsg == "ok") {
          const bookshelfs = this.bookshelfs;
          const inBookshelf = this.resultData[this.selected].list[index]
            .inBookshelf;
          if (inBookshelf == 0) {
            // 添加书架
            bookshelfs.unshift({
              ...this.resultData[this.selected].list[index],
              url: first_chapter_url,
              read_time: new Date().getTime(),
              ...res.result.data
            });
          } else if (inBookshelf == -1) {
            // 添加备用源
            bookshelfs.forEach(bs => {
              if (bs._id == res.result.data._id) {
                bs.other_sources = res.result.data.other_sources;
              }
            });
          }
          this.setBookshelfs(bookshelfs);
        } else {
          this.tui.toast(res.result.errMsg);
        }
        this.resultData[this.selected].list[index].loading = false;
      });
    },
    detail({ index }) {
      const { source_id, read_url } = this.resultData[this.selected].list[
        index
      ];
      uni.navigateTo({
        url:
          "/pages/detail/detail?source_id=" +
          source_id +
          "&read_url=" +
          read_url
      });
    },
    // 打开切换源
    showPopup() {
      this.popup = !this.popup;
    },
    // 关闭切换源的弹窗
    btnCloseDrop() {
      this.popup = false;
    },
    btnSelected(e) {
      this.selected = e.currentTarget.dataset.index;
      this.popup = false;
      if (this.showResult) {
        this.research();
      }
    },
    selecteSource(e) {
      if (e.detail.source == "touch") {
        this.selected = e.detail.current;
        this.research();
      }
    },
    research() {
      const { hasMore, list } = this.resultData[this.selected];
      if (hasMore && list.length == 0) {
        this.search(false);
      }
    }
  }
};
</script>

<style>
page {
  color: #333;
  background: #ffffff;
  height: 100%;
}

.container {
  /* padding: 0 30upx 30upx 30upx; */
  box-sizing: border-box;
  height: 100%;
}
.tui-searchbox {
  height: 128rpx;
  padding: 0 30rpx;
  padding-top: 30rpx;
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  background-color: #fff;
}

.swiper-content {
  flex: 1;
}

.swiper-item-content {
  display: flex;
  flex: 1;
  position: absolute;
  width: 100%;
  height: 100%;
  transform: translate(0%, 0px) translateZ(0px);
}

.tui-search-input {
  width: 100%;
  height: 66upx;
  border-radius: 35upx;
  padding: 0 30upx;
  box-sizing: border-box;
  background: #f2f2f2;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
}

.tui-input {
  flex: 1;
  color: #333;
  padding: 0 16upx;
  font-size: 28upx;
}

.tui-input-plholder {
  font-size: 28upx;
  color: #b2b2b2;
}

.tui-cancle {
  color: #888;
  font-size: 28upx;
  padding: 0 30upx;
  flex-shrink: 0;
  height: 72rpx;
  line-height: 72rpx;
}
.search-box {
  /* position: fixed; */
  z-index: 988;
  width: 100%;
}
.search-box-top {
  /* margin-top: 128rpx; */
  flex: 1;
}
.tui-search-history {
  padding: 0 30rpx;
}
.tui-search-hot {
  padding: 0 30rpx;
}
.tui-history-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 30upx 0;
}

.tui-icon-delete {
  padding: 10upx;
}

.tui-search-title {
  font-size: 28upx;
  font-weight: bold;
}

.tui-hot-header {
  padding: 30upx 0;
}

.tui-tag-class {
  display: inline-block !important;
  margin-bottom: 20upx;
  margin-right: 20upx;
  font-size: 26upx !important;
}
.story-description {
  width: 100%;
  font-size: 30rpx;
  word-break: break-all;
  word-wrap: break-word;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  box-sizing: border-box;
  margin-top: 10rpx;
  color: #80848f;
}
.tui-bottom-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* padding: 18upx 12upx; */
  border-radius: 40upx;
  box-sizing: border-box;
  background: #f2f2f2;
  margin-right: 20upx;
  white-space: nowrap;
  min-width: 150rpx;
  line-height: 66rpx;
}
.tui-btmItem-active {
  padding-bottom: 36upx;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.tui-bottom-text {
  line-height: 24upx;
  font-size: 24upx;
  max-width: 50%;
  overflow-x: hidden;
}
.tui-active {
  color: #6cc;
}
.tui-scroll-box {
  width: 100%;
  max-height: 480upx;
  box-sizing: border-box;
  position: relative;
  z-index: 99;
  color: #fff;
  font-size: 30upx;
  word-break: break-all;
}
.tui-seizeaseat-20 {
  height: 20upx;
}
.tui-drop-item {
  color: #333;
  height: 80upx;
  font-size: 28upx;
  padding: 20upx 40upx 20upx 40upx;
  box-sizing: border-box;
  /* display: inline-block; */
  /* width: 50%; */
}
.tui-bold {
  font-weight: bold;
}
.tui-ml {
  margin-left: 6upx;
}
.tui-middle {
  vertical-align: middle;
}
</style>
